package com.spa.domain.service;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.spa.application.command.admin.UserInfoAddCommand;
import com.spa.application.command.admin.UserInfoLogOffCommand;
import com.spa.application.command.member.MemberUserInfoEditCommand;
import com.spa.application.query.member.UserInfoQuery;
import com.spa.domain.entity.UserInfo;
import com.spa.infrastructure.mapper.UserInfoMapperStruct;
import com.spa.infrastructure.repository.condition.UserCollectionRefCondition;
import com.spa.infrastructure.repository.condition.UserInfoCondition;
import com.spa.infrastructure.repository.po.UserCollectionRefPO;
import com.spa.infrastructure.repository.po.UserInfoPO;
import com.spa.infrastructure.repository.service.UserCollectionRepositoryService;
import com.spa.infrastructure.repository.service.UserInfoRepositoryService;
import com.spa.infrastructure.util.SessionUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 用户信息  domain
 *
 * @author: lig
 * @date: 2023/12/7
 */
@Service
public class UserInfoService {

    @Resource
    private UserInfoRepositoryService userInfoRepositoryService;

    @Resource
    private UserCollectionRepositoryService userCollectionRepositoryService;

    @Resource
    private AuthUserService authUserService;

    public UserInfo userInfoOne(UserInfoQuery query) {
        return UserInfoMapperStruct.INSTANCE.po2Entity(userInfoRepositoryService.userInfo(UserInfoMapperStruct.INSTANCE.query2Condition(query)));
    }

    public UserInfo userInfoByPhoneOne(String phone) {
        UserInfoCondition condition = new UserInfoCondition();
        condition.setPhone(phone);
        return UserInfoMapperStruct.INSTANCE.po2Entity(userInfoRepositoryService.userInfo(condition));
    }

    public UserInfo userInfoById(Long id) {
        return UserInfoMapperStruct.INSTANCE.po2Entity(userInfoRepositoryService.getById(id));
    }

    /**
     * 运营端 用户分页
     *
     * @param userInfoQuery
     * @return
     */
    public Page<UserInfo> userInfoPage(com.spa.application.query.admin.UserInfoQuery userInfoQuery) {
        UserInfoCondition userInfoCondition = UserInfoMapperStruct.INSTANCE.query3Condition(userInfoQuery);
        Page<UserInfo> userInfoPage = UserInfoMapperStruct.INSTANCE.po2Entity4Page(userInfoRepositoryService.page(userInfoCondition));
        return userInfoPage;
    }

    /**
     * 修改信息
     *
     * @author: lig
     * @date: 2023/12/6
     */
    public void editUserInfo(MemberUserInfoEditCommand command) {
        userInfoRepositoryService.updateById(UserInfoMapperStruct.INSTANCE.command2Po(command));
    }

    /**
     * 注册用户
     *
     * @author: lig
     * @date: 2023-12-12
     */
    @Transactional
    public UserInfo registerUserInfo(UserInfoAddCommand command) {
        UserInfoCondition condition = new UserInfoCondition();
        condition.setPhone(command.getPhone());
        UserInfoPO userInfoPO = userInfoRepositoryService.userInfo(condition);
        if (BeanUtil.isNotEmpty(userInfoPO)) {
            return UserInfoMapperStruct.INSTANCE.po2Entity(userInfoPO);
        }

        userInfoPO = new UserInfoPO();
        userInfoPO.setPhone(command.getPhone());
        userInfoPO.setName(command.getPhone());
        userInfoPO.setRegTime(new Date());
        //注册系统用户
        userInfoRepositoryService.save(userInfoPO);

        return UserInfoMapperStruct.INSTANCE.po2Entity(userInfoPO);
    }


    /**
     * 统计全平台用户
     *
     * @return 用户数
     */
    public Long countAllUser() {
        return userInfoRepositoryService.countByCondition(new UserInfoCondition());
    }

    /**
     * 统计每天的新增用户数
     *
     * @return 新用户数量
     */
    public Long countNewUserPerDay() {
        LocalDate now = LocalDate.now();
        String beginTime = now + " 00:00:00";
        String endTime = now + " 23:59:59";
        UserInfoCondition userInfoCondition = new UserInfoCondition();
        userInfoCondition.setBeginTime(beginTime);
        userInfoCondition.setEndTime(endTime);
        return userInfoRepositoryService.countByCondition(userInfoCondition);
    }

    /**
     * 查询每天的新用户列表
     *
     * @return 新用户列表
     */
    public List<UserInfo> getNewUserListPerDay() {
        LocalDate now = LocalDate.now();
        String beginTime = now + " 00:00:00";
        String endTime = now + " 23:59:59";
        UserInfoCondition userInfoCondition = new UserInfoCondition();
        userInfoCondition.setBeginTime(beginTime);
        userInfoCondition.setEndTime(endTime);
        return UserInfoMapperStruct.INSTANCE.po2Entity4List(userInfoRepositoryService.list(userInfoCondition));
    }

    /**
     * 按时间查询用户列表
     *
     * @param beginTime 开始时间
     * @param endTime   结束时间
     * @return 用户列表
     */
    public List<UserInfo> getUserListByTime(String beginTime, String endTime) {
        UserInfoCondition userInfoCondition = new UserInfoCondition();
        userInfoCondition.setBeginTime(beginTime);
        userInfoCondition.setEndTime(endTime);
        return UserInfoMapperStruct.INSTANCE.po2Entity4List(userInfoRepositoryService.list(userInfoCondition));
    }

    /**
     * 按用户id获取用户列表
     *
     * @param ids
     * @return
     */
    public List<UserInfo> getUserListByIds(List<Long> ids) {
        UserInfoCondition userInfoCondition = new UserInfoCondition();
        userInfoCondition.setIds(ids);
        return UserInfoMapperStruct.INSTANCE.po2Entity4List(userInfoRepositoryService.list(userInfoCondition));
    }

    public Map<Long, UserInfo> groupById(List<UserInfo> userInfos) {
        return userInfos.stream().collect(Collectors.toMap(UserInfo::getId, Function.identity()));
    }


    /**
     * 获取是否收藏
     *
     * @author: lig
     * @date: 2024-01-13
     */
    public boolean getUserCollection(Long userId, Long massagistId) {

        Assert.isTrue(ObjectUtils.isNotEmpty(userId), "登录后可收藏");
        Assert.isTrue(ObjectUtils.isNotEmpty(massagistId), "需要确定收藏的技师");

        UserCollectionRefCondition condition = new UserCollectionRefCondition();
        condition.setUserId(userId);
        condition.setMassagistId(massagistId);
        if (CollUtil.isNotEmpty(userCollectionRepositoryService.listInfo(condition))) {
            return true;
        }
        return false;
    }

    /**
     * 用户收藏
     *
     * @author: lig
     * @date: 2024-01-13
     */
    public boolean userCollection(Long userId, Long massagistId) {

        Assert.isTrue(ObjectUtils.isNotEmpty(userId), "登录后可收藏");
        Assert.isTrue(ObjectUtils.isNotEmpty(massagistId), "需要确定收藏的技师");

        UserCollectionRefPO po = new UserCollectionRefPO();
        po.setUserId(userId);
        po.setMassagistId(massagistId);
        return userCollectionRepositoryService.save(po);
    }

    /**
     * 取消 用户收藏技师
     *
     * @author: lig
     * @date: 2024/1/9
     */
    public boolean cancelUserCollection(Long userId, Long massagistId) {

        Assert.isTrue(ObjectUtils.isNotEmpty(userId), "登录后可收藏");
        Assert.isTrue(ObjectUtils.isNotEmpty(massagistId), "需要确定收藏的技师");

        return userCollectionRepositoryService.delInfoByUserIdAndMassagist(userId, massagistId);
    }

    /**
     * 获取用户收藏技师数
     *
     * @author: lig
     * @date: 2024/1/9
     */
    public Integer userCollectionNum(Long userId) {

        if (ObjectUtils.isEmpty(userId)) return 0;
        UserCollectionRefCondition condition = new UserCollectionRefCondition();
        condition.setUserId(userId);
        List<UserCollectionRefPO> listPo = userCollectionRepositoryService.listInfo(condition);
        if (CollUtil.isNotEmpty(listPo)) {
            return listPo.size();
        }
        return 0;
    }


    /**
     * 获取用户收藏
     *
     * @return 技师ids
     * @author: lig
     * @date: 2024/1/9
     */
    public List<Long> myUserCollectionIds() {
        if (StpUtil.isLogin()) {
            Long userId = SessionUtil.getUser().getExtUserId();
            List<UserCollectionRefPO> userCollectionRefPOS = userCollectionRepositoryService.listInfoByUserId(userId);
            if (CollUtil.isNotEmpty(userCollectionRefPOS)) {
                return userCollectionRefPOS.stream().map(UserCollectionRefPO::getMassagistId).toList();
            }
        }
        return new ArrayList<>();
    }

    /**
     * 重置新用户
     *
     * @param userInfoLogOffCommand
     * @return
     */
    public Boolean logOffUser(UserInfoLogOffCommand userInfoLogOffCommand) {
        // 查询用户信息
        UserInfo userInfo = UserInfoMapperStruct.INSTANCE.po2Entity(userInfoRepositoryService.userInfo(UserInfoMapperStruct.INSTANCE.command2LogOff(userInfoLogOffCommand)));
        if (userInfo != null && userInfo.getPhone().length() == 11) {
            // 清空用户第三方授权
            authUserService.clearAuth(userInfoLogOffCommand.getId());
            // 强制注销用户
            StpUtil.logout(userInfo.getId());
            return userInfoRepositoryService.logOffUser(userInfoLogOffCommand.getId(), userInfo.getPhone());
        } else {
            return false;
        }
    }
}
